package com.zcx.springsecurity2.config;

import com.zcx.springsecurity2.Service.impl.MyUserDetailService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
import org.springframework.security.web.util.matcher.OrRequestMatcher;

/**
 * @Author:
 * @DATE:2023/6/19 11:35
 * @Description:
 * @Version 1.0
 */
@Configuration
public class WebSecurityConfigurer extends WebSecurityConfigurerAdapter {
//   @Bean
//   public UserDetailsService userDetailsService(){
//       InMemoryUserDetailsManager userDetailsService=new InMemoryUserDetailsManager();
//       userDetailsService.createUser(User.withUsername("aa").password("{noop}123").roles("admin").build());
//       return userDetailsService;
//   }
    @Autowired
    private MyUserDetailService myUserDetailService;


    //作用：用来将自定义AuthenticationManager在工厂中进行暴露，可以在任何位置注入
    @Override
    @Bean
    protected AuthenticationManager authenticationManager() throws Exception {
        return super.authenticationManager();
    }
    //自定义AuthenticationManager  推荐 并没有在工厂中暴露出来
    @Override
    public void configure(AuthenticationManagerBuilder builder) throws Exception {
        builder.userDetailsService(myUserDetailService);

    }
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests()
                .mvcMatchers("/login.html").permitAll()
                .mvcMatchers("/index").permitAll()  //放行资源写在前面
                .anyRequest().authenticated()
                .and()
                .formLogin()
                .loginPage("/login.html")  // 指定登录页的 url
                .loginProcessingUrl("/doLogin")  // 指定要处理认证的 url;
                //.successForwardUrl("/index")   //认证成功访问页面
                //.defaultSuccessUrl("")  //默认认证成功跳转页面，redirect，根据上一次保留的调整
                .successHandler(new MyAuthenticationSuccessHandler())  //认证成功时的处理,前后端分离处理方案
               // .failureForwardUrl("/login.html")    //认证失败之后 forward 跳转
               // .failureUrl("/login.html")  //默认认证失败之后 redirect 跳转
                .failureHandler(new MyAuthenticationFailureHandler())  //用来自定义认证失败之后失败处理 前后端分离解决方案
                .and()
                .logout()
                // .logoutUrl("/logout")  // 指定注销登录的 url，默认值为 "/logout"，默认采用 GET 请求方式
                .logoutRequestMatcher(new OrRequestMatcher(
                        new AntPathRequestMatcher("/logout2", "GET"),
                        new AntPathRequestMatcher("/logout3", "POST")
                ))  // 配置多个注销登录的 url 以及请求方式，OrRequestMatcher 表示只需满足多个请求中的一个即可生效，当然也有 AndRequestMatcher，同时满足才可生效，这里暂时不去过多解释
                .invalidateHttpSession(true)  // 是否让当前 Session 失效，默认为 true
                .clearAuthentication(true)  // 是否清除当前认证信息，默认为 true
                .logoutSuccessUrl("/login.html")  // 指定注销登录后返回的 url
                .and()
                .cors().disable();   //禁止

    }
}
